home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
pt20pc.zip
/
SEARCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-04
|
23KB
|
904 lines
#include "pt.h"
#include "string.h"
static unsigned char originalFromString[STRINGSIZE+1];
static unsigned char fromString[STRINGSIZE+1];
static unsigned char originalToString[STRINGSIZE+1];
static unsigned char toString[STRINGSIZE+1];
void pascal
/* XTAG:replaceText */
replaceText(w)
struct window *w;
{
extern struct window *selWindow;
extern long selBegin, selEnd;
extern int selMode;
extern unsigned char msgBuffer[];
extern unsigned char textBuffer[];
extern int ignoreCase;
extern int topOnFind;
extern long addPosition;
extern int nextChange;
extern struct changeItem *change;
extern unsigned int bytesLeft;
extern unsigned char *userMessages[];
extern unsigned int piecesLeft;
extern int debug;
extern struct openFile *files;
struct window *saveSelWindow;
long saveSelBegin, saveSelEnd, repEnd;
int n, fileId, fromLength;
int nLines, verify, replace, nReplaces;
int inSelection, diffLengths;
int saveIgnoreCase;
long cp, toLength, fSize;
unsigned char ch, *s;
struct piece *tempPP, *newPP;
struct changeItem *thisChange;
fileId = w->fileId;
fSize = fileSize(fileId);
nReplaces = 0;
/* check if this is a readOnly file */
if( files[fileId].readOnly ) {
sprintf(msgBuffer, userMessages[READONLYFILE],
files[fileId].origName);
msg(msgBuffer, 1);
return;
}
/* get the string to search for */
s = getInput("String to replace: ", originalFromString, 0);
/* ESCape or empty string cancels the replace */
if( s == NULL || s[0] == '\0' )
goto cancelReplace;
strncpy(originalFromString, s, STRINGSIZE+1);
s = originalFromString;
/* process the string to handle the newline, CR, and LF escapes */
n = 0;
saveIgnoreCase = ignoreCase;
while( 1 ) {
ch = *s;
if( isupper(ch) && ignoreCase /* case insensitive */)
ch = tolower(ch);
switch( ch ) {
case '\\':
ch = *++s;
if( ch == 'r' )
ch = '\r';
else if( ch == 'N' )
ch = '\n';
else if( ch == 'n' ) {
fromString[n++] = '\r';
ch = '\n';
}
break;
default:
break;
}
fromString[n++] = ch;
if( ch == '\0' )
break;
++s;
if( n >= STRINGSIZE )
--n;
}
/* get the replacment string */
sprintf(msgBuffer, "Replace `%s' with: ", originalFromString);
s = getInput(msgBuffer, originalToString, 0);
if( s == NULL )
goto cancelReplace;
strncpy(originalToString, s, STRINGSIZE);
s = originalToString;
/* process the replacement string for escapes */
n = 0;
while( 1 ) {
ch = *s++;
switch( ch ) {
case '\\':
ch = *s++;
if( ch == 'r' )
ch = '\r';
else if( ch == 'N' )
ch = '\n';
else if( ch == 'n' ) {
toString[n++] = '\r';
ch = '\n';
}
break;
default:
break;
}
toString[n++] = ch;
if( ch == '\0' )
break;
}
/* replace in the selection only? */
s = getInput("Globally (g) or Within Selection (s): ", "g", 1);
if( s == NULL )
goto cancelReplace;
else if( tolower(s[0]) == 'g' || s[0] == 'y' )
/* the getInput will return a 'y' of the left mouse button */
/* is clicked. Construe that as a 'g' and RMB ar an 's' */
inSelection = 0;
else
inSelection = 1;
/* verify each replacement? */
s = getInput("Verify each change? (y or n): ", "y", 1);
if( s == NULL ) {
cancelReplace:
msg("Replace cancelled", 1);
ignoreCase = saveIgnoreCase;
return;
}
/* save the verify boolean for later use */
verify = !(tolower(s[0]) == 'n');
/* Create a piece for the replacement string and record it in */
/* the piece buffer. This makes it easy to insert the replace */
/* string by copying this piece */
toLength = strlen(toString);
tempPP = getFreePiece();
tempPP->file = ADDFILE;
tempPP->position = addPosition;
for(n = 0; n < (int)toLength; n++ )
writeChar(toString[n], addPosition++);
tempPP->length = toLength;
/* start from the selection or the beginning */
if( inSelection ) {
cp = selBegin;
repEnd = selEnd;
w = selWindow;
} else {
if( w == selWindow )
cp = selBegin;
else
cp = 0;
repEnd = fSize;
}
/* How will the replace change character counts? */
/* we need to adjust repEnd after each replace */
diffLengths = strlen(toString) - strlen(fromString);
/* set things up so the line counts will be right */
if( readChar(fileId, cp) == '\n' )
nLines = 1;
else
nLines = 0;
/* save the location of the current selection */
if( !verify ) {
saveSelWindow = selWindow;
saveSelBegin = selBegin;
saveSelEnd = selEnd;
}
fromLength = strlen(fromString);
/* while loop to repeat the replace */
while( 1 ) {
if( !verify ) {
sprintf(msgBuffer, "Replace is %d%% completed",
(int)((100*cp)/fSize));
msg(msgBuffer, 1);
}
/* find the string */
cp = searchSpans(fileId, cp, repEnd, fromString, fromLength, &n);
nLines += n;
if( cp == (long)(-1) )
break;
if( selWindow != w ) {
eraseSelection();
selWindow = w;
}
selBegin = cp;
selEnd = selBegin + fromLength - 1;
selMode = SELCHAR;
/* remember where we came from */
selWindow->rowLastline = selWindow->numTopline;
/* replace? */
if( verify ) {
/* put the selection on the third line */
if( selBegin >= selWindow->posBotline
|| selBegin < selWindow->posTopline ) {
n = 3;
selWindow->posTopline = prevLine(fileId, selBegin, &n);
selWindow->numTopline += nLines - n;
}
(void)indentToShowSelection(-1);
/* show the string we found */
if( topOnFind )
topWindow(selWindow);
redrawWindow(selWindow);
sprintf(msgBuffer,
"[At %d%% of file] Replace this one? (y or n -- Esc to cancel) ",
(int)((100*cp)/fSize) );
s = getInput(msgBuffer, "y", 1);
if( s == NULL )
goto notFound;
replace = tolower(s[0])=='y';
} else
replace = 1;
/* do the replace */
if( replace ) {
deleteChars(selWindow->fileId, NOUPDATE, 0);
/* record in the change history */
IncrementNextChange();
thisChange = &change[nextChange];
thisChange->type = CINSERT;
thisChange->position = selBegin;
thisChange->length = toLength;
thisChange->fileId = selWindow->fileId;
newPP = getFreePiece();
newPP->file = ADDFILE;
newPP->position = tempPP->position;
newPP->length = toLength;
thisChange->firstPiece = newPP;
copyPieces(tempPP, selWindow, selBegin, toLength, verify);
cp = selBegin;
/* as we change the length of the text in the file with */
/* a replacement, we have to adjust repEnd so that we */
/* will not quit early */
repEnd += diffLengths;
if( inSelection ) {
/* if we are not verifying, we want the final */
/* selection to be the same as the original */
/* selection even though we are replaceing */
/* inside it. This makes the adjustment */
if( !verify )
saveSelEnd += diffLengths;
}
++nReplaces;
/* see if we are running out of space */
if( (bytesLeft < SPACELOW) && (piecesLeft <= 10) ) {
msg(userMessages[LOWSPACEMSG], 3);
goto notFound;
}
} else
cp = selBegin + 1;
}
notFound:
/* free the temp piece */
freePieces(tempPP);
/* restore the previous selection */
if( !verify ) {
selWindow = saveSelWindow;
selBegin = saveSelBegin;
selEnd = saveSelEnd;
redrawWindow(selWindow);
}
sprintf(msgBuffer, "Made %d replacement%s", nReplaces,
nReplaces==1?"":"s");
msg(msgBuffer, 1);
ignoreCase = saveIgnoreCase;
}
static unsigned char originalSearchString[STRINGSIZE+1];
static unsigned char searchString[STRINGSIZE+1];
static long foundCp; /* used to return cp in on-interactive search */
long pascal
/* XTAG:searchExternal */
searchExternal(s, w, newSearchMode, newIgnoreCase)
unsigned char *s;
struct window *w;
int newSearchMode, newIgnoreCase;
{
extern int ignoreCase;
extern int searchMode;
int saveSearchMode, saveIgnoreCase;
/* save and change the search mode state */
saveSearchMode = searchMode;
searchMode = newSearchMode;
saveIgnoreCase = ignoreCase;
ignoreCase = newIgnoreCase;
strncpy(originalSearchString, s, STRINGSIZE+1);
searchFor(3, w); /* 3 means non-int